#include "viml/debugger_cli.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>

namespace viml {

DebugDisplay::DebugDisplay(std::shared_ptr<Debugger> dbg, std::shared_ptr<DebugInfo> info)
    : debugger(dbg), debug_info(info)
    , show_instructions(false)
    , show_registers_flag(true)
    , show_stack_trace(true)
    , source_context_lines(5) {
}

// ========== 调试信息显示实现 ========== //

void DebugDisplay::show_current_location() {
    if (!debugger) return;

    std::cout << "\n当前位置: ";

    auto breakpoints = debugger->get_all_breakpoints();
    if (!breakpoints.empty()) {
        std::cout << "[断点] ";
    }

    // 显示当前PC和行号
    size_t pc = debugger->get_current_pc();
    int line = debugger->get_current_line();

    if (line > 0) {
        std::cout << "第 " << line << " 行 (PC=" << pc << ")";
    } else {
        std::cout << "PC=" << pc;
    }

    std::cout << std::endl;
}

void DebugDisplay::show_breakpoints() {
    if (!debugger) return;

    auto breakpoints = debugger->get_all_breakpoints();

    std::cout << "\n断点列表:\n";
    if (breakpoints.empty()) {
        std::cout << "  (无断点)\n";
        return;
    }

    for (const auto* bp : breakpoints) {
        std::cout << "  " << std::setw(3) << bp->id << ": ";

        if (!bp->enabled) {
            std::cout << "[禁用] ";
        }

        std::cout << "第 " << bp->location.line << " 行";

        if (!bp->condition.empty()) {
            std::cout << " (条件: " << bp->condition << ")";
        }

        if (bp->hit_count > 0) {
            std::cout << " (命中 " << bp->hit_count << " 次)";
        }

        std::cout << std::endl;
    }
}

void DebugDisplay::show_call_stack() {
    if (!debugger) return;

    auto call_stack = debugger->get_call_stack();

    std::cout << "\n调用栈:\n";
    if (call_stack.empty()) {
        std::cout << "  (空栈)\n";
        return;
    }

    for (size_t i = 0; i < call_stack.size(); ++i) {
        std::cout << "  #" << std::setw(2) << i << ": " << call_stack[i];
        if (i == 0) {
            std::cout << " [当前]";
        }
        std::cout << std::endl;
    }
}

void DebugDisplay::show_locals() {
    if (!debugger) return;

    std::cout << "\n局部变量:\n";

    auto variables = debugger->get_all_variables();
    if (variables.empty()) {
        std::cout << "  (无局部变量)\n";
        return;
    }

    // 简化实现：只显示所有变量
    for (const auto& pair : variables) {
        std::cout << "  " << std::setw(20) << std::left << pair.first
                  << " = " << format_value(pair.second) << std::endl;
    }
}

void DebugDisplay::show_globals() {
    if (!debugger) return;

    std::cout << "\n全局变量:\n";

    if (!debug_info) {
        std::cout << "  (调试信息不可用)\n";
        return;
    }

    // 简化实现：显示所有变量中的全局作用域变量
    auto variables = debugger->get_all_variables();
    int global_count = 0;

    for (const auto& pair : variables) {
        if (pair.first[0] == 'g' && pair.first.find('.') != std::string::npos) {
            std::cout << "  " << std::setw(20) << std::left << pair.first
                      << " = " << format_value(pair.second) << std::endl;
            global_count++;
        }
    }

    if (global_count == 0) {
        std::cout << "  (无全局变量)\n";
    }
}

void DebugDisplay::show_registers() {
    if (!debugger) return;

    std::cout << "\n寄存器状态:\n";

    // 这里需要通过VM获取寄存器信息
    // 简化实现，显示前10个寄存器
    for (int i = 0; i < 10; ++i) {
        // 假设有一个获取寄存器值的方法
        std::cout << "  R" << std::setw(2) << i << ": " << "<无法获取>" << std::endl;
    }
}

void DebugDisplay::show_source_context() {
    if (!debugger || !debug_info) return;

    int current_line = debugger->get_current_line();
    if (current_line <= 0) return;

    std::cout << "\n源码上下文 (第 " << current_line << " 行):\n";

    // 显示当前行高亮
    for (int i = -source_context_lines; i <= source_context_lines; ++i) {
        int line_num = current_line + i;
        if (line_num < 1) continue;

        std::string source_line = debug_info->get_source_line(line_num);
        if (source_line.empty()) continue;

        std::cout << "  " << std::setw(4) << line_num << " | ";

        if (i == 0) {
            // 高亮当前行
            std::cout << "\033[1;32m" << source_line << "\033[0m"; // 红色高亮
        } else {
            std::cout << source_line;
        }
        std::cout << std::endl;
    }
}

void DebugDisplay::show_disassembly(size_t start_pc, size_t count) {
    if (!debugger || !debug_info) return;

    std::cout << "\n反汇编输出 (从 PC=" << start_pc << ", 显示 " << count << " 条指令):\n";

    // 这里需要访问VM的字节码信息
    std::cout << "  (反汇编功能需要VM字节码访问)\n";
}

// ========== 帮助信息显示实现 ========== //

void DebugDisplay::show_help(const std::string& command) {
    if (command.empty()) {
        // 显示总体帮助
        show_general_help();
    } else {
        // 显示特定命令的帮助
        show_command_help(command);
    }
}

void DebugDisplay::show_general_help() {
    std::cout << "\nVimL调试器命令帮助:\n\n";

    std::cout << "基础命令:\n";
    std::cout << "  help, h [command]     - 显示帮助信息\n";
    std::cout << "  quit, q, exit       - 退出调试器\n";
    std::cout << "  continue, c, run     - 继续执行程序\n";
    std::cout << "  step, next, n       - 单步执行\n";
    std::cout << "  stepinto, si        - 单步进入函数\n";
    std::cout << "  stepover, so        - 单步跳过函数\n";
    std::cout << "  stepout, finish      - 单步退出当前函数\n\n";

    std::cout << "断点命令:\n";
    std::cout << "  break, b [line]     - 在指定行设置断点\n";
    std::cout << "  clear, delete [bp]  - 清除指定断点\n";
    std::cout << "  delete, del [bp]    - 删除指定断点\n";
    std::cout << "  list, info          - 显示所有断点\n\n";

    std::cout << "信息查看命令:\n";
    std::cout << "  where, bt           - 显示当前位置和调用栈\n";
    std::cout << "  backtrace, bt       - 显示完整调用栈\n";
    std::cout << "  locals, l            - 显示局部变量\n";
    std::cout << "  globals, g          - 显示全局变量\n";
    std::cout << "  print, p [expr]     - 显示表达式值\n\n";

    std::cout << "高级命令:\n";
    std::cout << "  frame, f [num]      - 选择调用栈帧\n";
    std::cout << "  up, u                - 向上移动栈帧\n";
    std::cout << "  down, d              - 向下移动栈帧\n";
    std::cout << "  disassemble, x [n]   - 显示反汇编\n\n";
}

void DebugDisplay::show_command_help(const std::string& command) {
    std::cout << "\n命令详细帮助: " << command << "\n";

    if (command == "break" || command == "b") {
        std::cout << "用法: break <行号>\n";
        std::cout << "示例: break 15        # 在第15行设置断点\n";
        std::cout << "      break 25 10     # 在第25行设置条件断点\n";
    } else if (command == "continue" || command == "c") {
        std::cout << "用法: continue\n";
        std::cout << "描述: 继续执行程序，直到下一个断点或程序结束\n";
    } else if (command == "step" || command == "n") {
        std::cout << "用法: step\n";
        std::cout << "描述: 单步执行下一条指令\n";
    } else {
        std::cout << "未知命令: " << command << "\n";
    }
}

// ========== 状态信息显示实现 ========== //

void DebugDisplay::show_welcome() {
    std::cout << "\n=== VimL 调试器 ===\n";
    std::cout << "输入 'help' 获取命令帮助，输入 'quit' 退出调试器\n";
    std::cout << "========================\n";
}

void DebugDisplay::show_goodbye() {
    std::cout << "\n调试器已退出。\n";
}

void DebugDisplay::show_error(const std::string& error) {
    std::cout << "\n\033[1;31m错误: " << error << "\033[0m\n";
}

void DebugDisplay::show_info(const std::string& info) {
    std::cout << "\n信息: " << info << "\n";
}

// ========== 辅助格式化方法 ========== //

std::string DebugDisplay::format_value(const Value& value) {
    return value.to_string();
}

std::string DebugDisplay::format_source_line(int line, const std::string& prefix) {
    if (!debug_info) return "";

    std::string source = debug_info->get_source_line(line);
    if (source.empty()) return prefix + "(源码不可用)";

    return prefix + source;
}

std::string DebugDisplay::format_frame_info(size_t frame_index) {
    auto call_stack = debugger->get_call_stack();

    if (frame_index >= call_stack.size()) {
        return "无效的栈帧";
    }

    std::ostringstream oss;
    oss << "栈帧 #" << frame_index << ": " << call_stack[frame_index];

    if (frame_index == 0) {
        oss << " [当前]";
    }

    return oss.str();
}

} // namespace viml